/*
 * Copyright (C) 2023 KylinSoftCo., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
**/
#include "personalizeddata.h"

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>
#include <QJsonArray>
#include <QFile>
#include <QDate>
#include <QTime>

enum enum_operation
{
    enum_operation_update = 0,
    enum_operation_add,
    enum_operation_del,
};

PersonalizedData::PersonalizedData(QString user)
{
    KyInfo() << user;
    m_user = user;
    m_usd_conf_path = QString("/var/lib/lightdm-data/%1/usd/config/ukui-settings-daemon.settings").arg(m_user);
    m_greeter_conf_path = QString("/var/lib/lightdm-data/%1/ukui-greeter.conf").arg(m_user);
    m_file_watch = new QFileSystemWatcher();
    connect(m_file_watch, &QFileSystemWatcher::fileChanged, this, &PersonalizedData::fileChanged);
    this->__load_conf_ukuigreeterconf();
    //无需读取usd配置
    //this->__load_conf_usd_conf();

}

PersonalizedData::~PersonalizedData()
{
    KyInfo() << m_user;
    if(0 != m_conf_TimerID)
    {
        this->killTimer(m_conf_TimerID);
        m_conf_TimerID = 0;
    }
    if(nullptr != m_file_watch)
    {
        delete m_file_watch;
        m_file_watch = nullptr;
    }

}

void PersonalizedData::getJsonData(QJsonObject & json)
{
    json["user"] = m_user;
    {
        QJsonObject json_1;
        json_1["dateType"] = m_dateType;
        json_1["fontSize"] = m_fontSize;
        json_1["timeType"] = m_timeType;
        json_1["backgroundPath"] = m_backgroundPath;
        json_1["color"] = m_color;
        json["greeter"] = json_1;
    }
}

QString PersonalizedData::getJsonData()
{
    QJsonObject json;
    this->getJsonData(json);
    json["operation"] = enum_operation_update;
    QJsonDocument document;
    document.setObject(json);
    return document.toJson(QJsonDocument::Compact);
}

void PersonalizedData::fileChanged(const QString &path)
{
    KyInfo() << path;
    if(m_greeter_conf_path == path)
    {
        m_greeter_conf_path_changed = true;
    }
    if(m_usd_conf_path == path)
    {
        m_usd_conf_path_changed = true;
    }

    if(0 != m_conf_TimerID)
    {
        this->killTimer(m_conf_TimerID);
        m_conf_TimerID = 0;
    }
    m_conf_TimerID = this->startTimer(100);
}

void PersonalizedData::timerEvent(QTimerEvent *event)
{
    KyInfo() << m_file_watch->files();
    if(event->timerId() == m_conf_TimerID)
    {
        this->killTimer(m_conf_TimerID);
        m_conf_TimerID = 0;

        if(m_greeter_conf_path_changed)
        {
            m_greeter_conf_path_changed = false;
            this->__load_conf_ukuigreeterconf();
        }
        if(m_usd_conf_path_changed)
        {
            m_usd_conf_path_changed = false;
            this->__load_conf_usd_conf();
        }
        emit KYLINUSERDATAMNG::getInstance()->conf_changed(this->getJsonData());
    }
}

int PersonalizedData::__load_conf_ukuigreeterconf()
{
    KyInfo();
    QSettings conf(m_greeter_conf_path, QSettings::IniFormat);
    if(QSettings::NoError != conf.status())
    {
        KyWarning() << m_greeter_conf_path << conf.status();
        return -1;
    }

    if(conf.childGroups().contains("Greeter"))
    {
        conf.beginGroup("Greeter");

        if(conf.contains("dateType"))
            m_dateType = conf.value("dateType", m_dateType).toString();

        if(conf.contains("fontSize"))
            m_fontSize = conf.value("fontSize", m_fontSize).toInt();

        if(conf.contains("timeType"))
            m_timeType = conf.value("timeType", m_timeType).toInt();

        conf.endGroup();
    }

    if(conf.childGroups().contains("greeter"))
    {
        conf.beginGroup("greeter");

        if(conf.contains("backgroundPath"))
        {
            m_backgroundPath = conf.value("backgroundPath", m_backgroundPath).toString();
            if(!m_backgroundPath.isEmpty())
            {
                m_backgroundPath = this->__copy_file(m_backgroundPath);
            }
        }


        if(conf.contains("color"))
            m_color = conf.value("color", m_color).toString();

        conf.endGroup();
    }

    if(nullptr != m_file_watch && !m_file_watch->files().contains(m_greeter_conf_path))
    {
        m_file_watch->addPath(m_greeter_conf_path);
    }
    return 0;
}

int PersonalizedData::__load_conf_usd_conf()
{
    KyInfo();
    QSettings conf(m_usd_conf_path, QSettings::IniFormat);
    if(QSettings::NoError != conf.status())
    {
        KyWarning() << m_usd_conf_path << conf.status();
        return -1;
    }

    if(conf.childGroups().contains("xsettings"))
    {
        conf.beginGroup("xsettings");

        if(conf.contains("cursor-size"))
            m_cursor_size = conf.value("cursor-size", m_cursor_size).toInt();

        if(conf.contains("cursor-theme"))
            m_cursor_theme = conf.value("cursor-theme", m_cursor_theme).toString();

        if(conf.contains("scaling-factor"))
            m_scaling_factor = conf.value("scaling-factor", m_scaling_factor).toInt();

        conf.endGroup();
    }

    if(nullptr != m_file_watch && !m_file_watch->files().contains(m_usd_conf_path))
    {
        m_file_watch->addPath(m_usd_conf_path);
    }
    return 0;
}

QString PersonalizedData::__copy_file(QString oldfile)
{
    if(QFile::exists(oldfile))
    {
        QString newfile = "/tmp/loginBackground-" + m_user;
        QDate d =QDate::currentDate();
        newfile += d.toString("yyyy-MM-dd");
        if(QFile::exists(newfile))
        {
            QFile::remove(newfile);
        }
        if(QFile::copy(oldfile, newfile))
        {
            return newfile;
        }
    }
    return "";
}



/////////////////////////PersonalizedDataMng//////////////////////////////////////

PersonalizedDataMng::PersonalizedDataMng(void)
{
    m_usersModel = new QLightDM::UsersModel(this);
    connect(m_usersModel, &QAbstractListModel::rowsInserted, this, &PersonalizedDataMng::onUserAdded);
    connect(m_usersModel, &QAbstractListModel::rowsRemoved, this, &PersonalizedDataMng::onUserRemoved);
    this->__updateUsersInfo();
}

PersonalizedDataMng::~PersonalizedDataMng()
{
    if(nullptr != m_usersModel)
    {
        delete m_usersModel;
        m_usersModel = nullptr;
    }
}

QString PersonalizedDataMng::GetConfInformation(QString name)
{
    QJsonObject json;
    if(m_userPersonalizedData.contains(name))
    {
        QJsonObject json1;
        m_userPersonalizedData[name]->getJsonData(json1);
        json[name] = json1;
    }
    else if(name.isEmpty())
    {
        for(auto & it : m_userPersonalizedData.toStdMap())
        {
            QJsonObject json1;
            it.second->getJsonData(json1);
            json[it.first] = json1;
        }
    }
    else if("lightdm" == name)
    {
        QString tmp(m_lightdm_str);
        m_lightdm_str = "";
        return tmp;
    }

    QJsonDocument document;
    document.setObject(json);
    QString strJson(document.toJson(QJsonDocument::Compact));
    KyDebug() << strJson;
    return strJson;
}

void PersonalizedDataMng::SetLoginSynInformation(QString val)
{
    m_lightdm_str = val;
}

void PersonalizedDataMng::onUserAdded(const QModelIndex &, int left, int right)
{
    if(!m_usersModel)
        return;

    for(int i = left; i <= right; i++)
    {
        QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString();
        KyInfo() << left << right << name;
        if(!name.isEmpty())
        {
             m_userPersonalizedData[name] = KylinUserDatePtr(new PersonalizedData(name));

             QJsonObject json;
             m_userPersonalizedData[name]->getJsonData(json);
             json["operation"] = enum_operation_add;
             QJsonDocument document;
             document.setObject(json);
             emit conf_changed(document.toJson());
        }
    }
}

void PersonalizedDataMng::onUserRemoved(const QModelIndex &, int, int)
{
    if(!m_usersModel)
        return;

    auto tmp = m_userPersonalizedData;
    for(int i = 0; i < m_usersModel->rowCount(QModelIndex()); i++)
    {
        QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString();
        if(!name.isEmpty())
            tmp.remove(name);
    }

    if(tmp.size() > 0)
    {
        KyInfo() << tmp.begin().key();
        m_userPersonalizedData.remove(tmp.begin().key());

        QJsonObject json;
        json["operation"] = enum_operation_del;
        json["user"] = tmp.begin().key();
        QJsonDocument document;
        document.setObject(json);
        emit conf_changed(document.toJson());
    }
}

void PersonalizedDataMng::__updateUsersInfo()
{
    if (m_usersModel)
    {
        for(int i = 0; i < m_usersModel->rowCount(QModelIndex()); i++)
        {
            QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString();
            if(!name.isEmpty())
            {
                m_userPersonalizedData[name] = KylinUserDatePtr(new PersonalizedData(name));
            }

        }
    }
}



